home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / mailcli.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-27  |  7.8 KB  |  369 lines

  1. /* Mail Command Line Interface -- Clients
  2.  * Copyright 1992 William Allen Simpson
  3.  *    partly based on a MAIL client design by Anders Klemets, SM0RGV
  4.  *
  5.  * Mods by PA0GRI
  6.  * Improved param cracking
  7.  */
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include "global.h"
  13. #include "timer.h"
  14. #include "proc.h"
  15. #include "socket.h"
  16. #include "domain.h"
  17. #include "cmdparse.h"
  18. #include "files.h"
  19. #include "netuser.h"
  20. #include "mailcli.h"
  21. #include "mailutil.h"
  22. #include "smtp.h"
  23.  
  24.  
  25. /* Tracing levels:
  26.     0 - no tracing
  27.     1 - serious errors reported
  28.     2 - transient errors reported
  29.     3 - session progress reported
  30.  */
  31. unsigned short Mailtrace = 1;
  32.  
  33. int Mailquiet = FALSE;
  34.  
  35. struct mailservers *Mailservers = NULLMAIL;
  36.  
  37. static int domsquiet __ARGS((int argc,char *argv[],void *p));
  38. static int domstrace __ARGS((int argc,char *argv[],void *p));
  39. static int doadds __ARGS((int argc,char *argv[],void *p));
  40. static int dodrops __ARGS((int argc,char *argv[],void *p));
  41. static int dokicks __ARGS((int argc,char *argv[],void *p));
  42. static int dolists __ARGS((int argc,char *argv[],void *p));
  43.  
  44. static void mailtick __ARGS((void *tp));
  45.  
  46. static char mreaderr[] = "popmail: Missing";
  47.  
  48. static struct cmds Mailcmds[] = {
  49.     "addserver",    doadds,         0, 2, "popmail addserver <mailserver> [<seconds>] [hh:mm-hh:mm] <protocol> <mailbox> <username> <password>",
  50.     "dropserver",   dodrops,        0, 2, "popmail dropserver <mailserver>",
  51.     "kick",         dokicks,        0, 2, "popmail kick <mailserver>",
  52.     "list",         dolists,        0, 0, NULLCHAR,
  53.     "quiet",        domsquiet,      0, 0, NULLCHAR,
  54.     "trace",        domstrace,      0, 0, NULLCHAR,
  55.     NULLCHAR,
  56. };
  57.  
  58.  
  59. int
  60. domsread(argc,argv,p)
  61. int argc;
  62. char *argv[];
  63. void *p;
  64. {
  65.     return subcmd(Mailcmds,argc,argv,p);
  66. }
  67.  
  68.  
  69. static int
  70. domsquiet(argc,argv,p)
  71. int argc;
  72. char *argv[];
  73. void *p;
  74. {
  75.     return setbool(&Mailquiet,"mail quiet",argc,argv);
  76. }
  77.  
  78.  
  79. static int
  80. domstrace(argc, argv, p)
  81. int argc;
  82. char *argv[];
  83. void *p;
  84. {
  85.     return setshort(&Mailtrace,"mail tracing",argc,argv);
  86. }
  87.     
  88.  
  89.  
  90. static int
  91. doadds(argc,argv,p)
  92. int argc;
  93. char *argv[];
  94. void *p;
  95. {
  96.     struct mailservers *np;
  97.     char *fullname;
  98.     int i;
  99.     int32 addr;
  100.  
  101.     fullname = domainsuffix(argv[1]);
  102.     if((addr = resolve(fullname)) == 0L){
  103.         tprintf("Unknown host %s\n",fullname);
  104.         /* domainsuffix() ALLOCATED memory !, so free it - WG7J */
  105.         free(fullname);
  106.         return 1;
  107.     }
  108.  
  109.     i = 2;
  110.     np = (struct mailservers *) callocw(1,sizeof(struct mailservers));
  111.     np->hostname = fullname;
  112.     np->next = Mailservers;
  113.     Mailservers = np;
  114.     np->lowtime = np->hightime = -1;
  115.     np->timer.func = mailtick;  /* what to call on timeout */
  116.     np->timer.arg = (void *)np;
  117.  
  118.     if( argc > i && isdigit(*argv[i])){
  119.         if(strchr(argv[i],'-') == NULLCHAR ) 
  120.             /* set timer duration */
  121.             set_timer(&np->timer,atol(argv[i++])*1000L);
  122.     }
  123.  
  124.     if( argc > i && isdigit(*argv[i])){
  125.         int lh, ll, hh, hl;
  126.         sscanf(argv[i++], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
  127.         np->lowtime = lh * 100 + ll;
  128.         np->hightime = hh * 100 + hl;
  129.     }
  130.  
  131.     if ( argc > i ) {
  132.         struct daemon *dp = Mailreaders;
  133.  
  134.         for ( ; dp->name != NULLCHAR ; dp++ ) {
  135.             if ( stricmp(dp->name, argv[i]) == 0 ) {
  136.                 np->reader = dp;
  137.                 break;
  138.             }
  139.         }
  140.         if ( np->reader == NULLDAEMON ) {
  141.             tprintf("unrecognized protocol '%s'\n", argv[i] );
  142.             goto quit;
  143.         }
  144.         i++;
  145.     } else {
  146.         tprintf("%s protocol\n",mreaderr);
  147.         goto quit;
  148.     }
  149.  
  150.     if ( argc > i ) {
  151.         np->mailbox = strdup(argv[i++]);
  152.     } else {
  153.         tprintf("%s mailbox\n",mreaderr);
  154.         goto quit;
  155.     }
  156.  
  157.     if ( argc > i ) {
  158.         np->username = strdup(argv[i++]);
  159.     } else {
  160.         tprintf("%s username\n",mreaderr);
  161.         goto quit;
  162.     }
  163.  
  164.     if ( argc > i ) {
  165.         np->password = strdup(argv[i++]);
  166.     } else {
  167.         tprintf("%s password\n",mreaderr);
  168.         goto quit;
  169.     }
  170.  
  171.     start_timer(&np->timer);        /* and fire it up */
  172.     return 0;
  173.  
  174. quit:
  175.     Mailservers = np->next;
  176.     free(np->hostname);
  177.     free(np->username);
  178.     free(np->password);
  179.     free(np->mailbox);
  180.     free((char *)np);
  181.     return -1;
  182. }
  183.  
  184.  
  185. static int
  186. dodrops(argc,argv,p)
  187. int argc;
  188. char *argv[];
  189. void *p;
  190. {
  191.     struct mailservers *np, *npprev = NULLMAIL;
  192.     char *fullname;
  193.  
  194.     fullname = domainsuffix(argv[1]);
  195.     for (np = Mailservers; np != NULLMAIL; npprev = np, np = np->next) {
  196.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  197.             stop_timer(&np->timer);
  198.             free(np->hostname);
  199.             free(np->username);
  200.             free(np->password);
  201.             free(np->mailbox);
  202.  
  203.             if(npprev != NULLMAIL)
  204.                 npprev->next = np->next;
  205.             else
  206.                 Mailservers = np->next;
  207.             free((char *)np);
  208.             return 0;
  209.         }
  210.     }
  211.     tprintf("No such server enabled.\n");
  212.     return -1;
  213. }
  214.  
  215.  
  216. static int
  217. dolists(argc,argv,p)
  218. int argc;
  219. char *argv[];
  220. void *p;
  221. {
  222.     struct mailservers *np;
  223.  
  224.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  225.         char tbuf[80];
  226.         if (np->lowtime != -1 && np->hightime != -1)
  227.             sprintf(tbuf, " %02d:%02d-%02d:%02d",
  228.                 np->lowtime/100,
  229.                 np->lowtime%100,
  230.                 np->hightime/100,
  231.                 np->hightime%100);
  232.         else
  233.             tbuf[0] = '\0';
  234.         tprintf("%-32s (%lu/%lu%s) %s %s\n",
  235.             np->hostname,
  236.             read_timer(&np->timer) /1000L,
  237.             dur_timer(&np->timer) /1000L,
  238.             tbuf,
  239.             np->reader->name,
  240.             np->username );
  241.     }
  242.     return 0;
  243. }
  244.  
  245.  
  246. static int
  247. dokicks(argc,argv,p)
  248. int argc;
  249. char *argv[];
  250. void *p;
  251. {
  252.     struct mailservers *np;
  253.     char *fullname;
  254.  
  255.     fullname = domainsuffix(argv[1]);
  256.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  257.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  258.             if(availmem() - np->reader->stksize < Memthresh){
  259.                 tprintf("insufficient memory\n");
  260.                 return 1;
  261.             }
  262.             /* If the timer is not running, the timeout function
  263.              * has already been called, and we don't want to call
  264.              * it again.
  265.              */
  266.             if ( np->timer.duration == 0
  267.               || run_timer(&np->timer) ) {
  268.                 stop_timer(&np->timer);
  269.                 newproc( np->reader->name,
  270.                     np->reader->stksize,
  271.                     np->reader->fp,
  272.                     0, np, NULL,0);
  273.             }
  274.             return 0;
  275.         }
  276.     }
  277.     tprintf("No such server enabled.\n");
  278.     return -1;
  279. }
  280.  
  281.  
  282. static void
  283. mailtick(tp)
  284. void *tp;
  285. {
  286.     struct mailservers *np = tp;
  287.     struct tm *ltm;
  288.     time_t t;
  289.     int now;
  290.  
  291.     if(availmem() - np->reader->stksize < Memthresh){
  292.         /* Memory is tight, don't do anything */
  293.         if (Mailtrace >= 2)
  294.             log(-1,"%s tick exit -- low memory",
  295.                 np->reader->name);
  296.         start_timer(&np->timer);
  297.         return;
  298.     }
  299.  
  300.     time(&t);
  301.     ltm = localtime(&t);
  302.     now = ltm->tm_hour * 100 + ltm->tm_min;
  303.     if (np->lowtime < np->hightime) {  /* doesn't cross midnight */
  304.         if (now < np->lowtime || now >= np->hightime) {
  305.             if (Mailtrace >= 2)
  306.                 log(-1,"%s window to '%s' not open",
  307.                     np->reader->name,
  308.                     np->hostname);
  309.             start_timer(&np->timer);
  310.             return;
  311.         }
  312.     } else {
  313.         if (now < np->lowtime && now >= np->hightime) {
  314.             if (Mailtrace >= 2)
  315.                 log(-1,"%s window to '%s' not open",
  316.                     np->reader->name,
  317.                     np->hostname);
  318.             start_timer(&np->timer);
  319.             return;
  320.         }
  321.     }
  322.  
  323.     newproc( np->reader->name, np->reader->stksize, np->reader->fp,
  324.         0, tp, NULL,0);
  325. }
  326.  
  327.  
  328. int
  329. mailresponse(s,buf,comment)
  330. int s;        /* Socket index */
  331. char *buf;    /* User buffer */
  332. char *comment;    /* comment for error message */
  333. {
  334.     if (recvline(s,buf,RLINELEN) != -1) {
  335.         if ( Mailtrace >= 3 ) {
  336.             rip(buf);
  337.             log(s,"%s <== %s", comment, buf);
  338.         }
  339.         return 0;
  340.     }
  341.     if ( Mailtrace >= 2 )
  342.         log(s,"receive error for %s response", comment);
  343.     return -1;
  344. }
  345.  
  346.  
  347. /* Check to see if mailbox is already busy (or perpetually locked) */
  348. int
  349. mailbusy( np )
  350. struct mailservers *np;
  351. {
  352.     int countdown = 10;
  353.  
  354.     while ( mlock( Mailspool, np->mailbox ) ) {
  355.         if ( --countdown > 0 ) {
  356.             mspause( 60000L ); /* 60 seconds */
  357.         } else {
  358.             start_timer(&np->timer);
  359.             return TRUE;
  360.         }
  361.     }
  362.  
  363.     /* release while processing */
  364.     rmlock( Mailspool, np->mailbox );
  365.     return FALSE;
  366. }
  367.  
  368.  
  369.